/**
 *******************************************************************************
 * @file  efm/efm_swap/source/main.c
 * @brief Main program of EFM for the Device Driver Library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2023-05-31       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "main.h"

/**
 * @addtogroup HC32F448_DDL_Examples
 * @{
 */

/**
 * @addtogroup EFM_Swap
 * @{
 */

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
#define LED3_G_PORT         (GPIO_PORT_A)
#define LED3_G_PIN          (GPIO_PIN_02)

#define KEY5_PORT           (GPIO_PORT_B)
#define KEY5_PIN            (GPIO_PIN_06)

/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @brief  GPIO config
 * @param  None
 * @retval None
 */
static void GPIO_Config(void)
{
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinState = PIN_STAT_SET;
    stcGpioInit.u16PinDir = PIN_DIR_OUT;
    (void)GPIO_Init(LED3_G_PORT, LED3_G_PIN, &stcGpioInit);

    stcGpioInit.u16PullUp = PIN_PU_ON;
    stcGpioInit.u16PinDir = PIN_DIR_IN;
    (void)GPIO_Init(KEY5_PORT, KEY5_PIN, &stcGpioInit);
}

/**
 * @brief  EFM config
 * @param  None
 * @retval None
 */
static void EFM_Config(void)
{
    en_int_status_t flag;

    /* Enable EFM */
    EFM_Cmd(EFM_CHIP_ALL, ENABLE);
    MODIFY_REG32(CM_EFM->FWMC, EFM_FWMC_PEMOD, EFM_MD_READONLY);
    /* Wait flash ready. */
    do {
        flag = EFM_GetStatus(EFM_FLAG_RDY);
    } while (SET != flag);

    /* EFM_FWMC wirte enable */
    EFM_FWMC_Cmd(ENABLE);
    EFM_ClearStatus(EFM_FLAG_ALL);
}

/**
 * @brief  Main function of EFM project
 * @param  None
 * @retval int32_t return value, if needed
 */
int32_t main(void)
{
    uint32_t u32DelayTime = 100U;
    en_functional_state_t en_swap;

    /* Register write enable for some required peripherals. */
    LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_FCG | LL_PERIPH_EFM | LL_PERIPH_SRAM);
    /* GPIO init */
    GPIO_Config();
    EFM_Config();
    /* Register write protected for some required peripherals. */
    LL_PERIPH_WP(LL_PERIPH_FCG | LL_PERIPH_SRAM);

    /* Determine the led twinkle time base on the boot swap is enabled or not */
    if (RW_MEM32(EFM_SWAP_ADDR) == EFM_SWAP_DATA) {
        u32DelayTime = 100U;
        en_swap = DISABLE;
    } else {
        u32DelayTime = 500U;
        en_swap = ENABLE;
    }

    /* LED twinkle */
    do {
        GPIO_TogglePins(LED3_G_PORT, LED3_G_PIN);
        DDL_DelayMS(u32DelayTime);
    } while (PIN_SET == GPIO_ReadInputPins(KEY5_PORT, KEY5_PIN));

    DDL_DelayMS(300U);
    /* Press KEY5, then to swap */
    if (LL_OK == EFM_SwapCmd(en_swap)) {
        NVIC_SystemReset();

    }
    for (;;) {
        ;
    }
}

/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
